package com.moon.controller;

import com.moon.dao.TUserMapper;
import com.moon.entity.TUser;
import com.moon.service.VerificationCodeService;
import com.moon.utils.*;
import com.moon.vo.TUserVo;
import com.netflix.ribbon.proxy.annotation.Http;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户管理
 */
@Controller
@CrossOrigin("*")
@RequestMapping("/user")
public class UserController {
    @Autowired
    TUserMapper tUserMapper;
    @Autowired
    @Qualifier("idWorker1")
    IdWorker idWorker;

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    TemplateEngine templateEngine;

    @Autowired
    private VerificationCodeService verificationCodeService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 用户登录
     * @param user
     * @return
     * @throws NoSuchAlgorithmException
     */
    @RequestMapping("/login")
    @ResponseBody
    public Map<String, Object> login(@RequestBody TUser user) throws NoSuchAlgorithmException {
        System.out.println("登录中");
        String account = user.getAccount();
        System.out.println(account);
        System.out.println("-----");
        String password = user.getPassword();
        TUser tUser = new TUser();
        if ("".equals(password) || password==null){
            return null;        }
        //密码加密
        String hashedPassword = PasswordUtils.passwordEncrypt(password);
        System.out.println(hashedPassword);
        //匹配密码
        tUser.setAccount(account);
        tUser.setPassword(hashedPassword);
        TUser userRes = tUserMapper.selectOne(tUser);
        if (userRes == null) {
            Map<String, Object> map2 = new HashMap<>();
            map2.put("state","error");
            return map2;
        }
        userRes.setPassword("");
        String token = JwtUtils.getToken(userRes,3600000*2);
        Map<String, Object> map = new HashMap<>();
        map.put("token",token);
        map.put("account",account);
        map.put("nickname",userRes.getNickname());
        System.out.println("登录成功");

        return map;
    }

    /**
     * 上传文件
     * @param file
     * @return String
     * @throws IOException
     */
    @RequestMapping("/upload")
    public String uploadFile(@RequestParam("image") MultipartFile file) throws IOException {
        String uploadDirectory = "static/imgs"; // 定义上传文件保存的目录
        Path filePath = Paths.get(uploadDirectory + file.getOriginalFilename()); // 构建上传文件的路径
        Files.createDirectories(filePath.getParent()); // 创建文件所在的目录
        Files.write(filePath, file.getBytes()); // 保存上传文件

        String imageUrl = "/" + uploadDirectory + file.getOriginalFilename(); // 构建图片的URL
        // ...在此处将图片URL返回给前端
        return "{\"userImg\": \"" + imageUrl + "\"}";
    }

    /**
     * 注册用户
     * @param tUserVo
     * @return String
     * @throws NoSuchAlgorithmException
     */
    @RequestMapping("register")
    @ResponseBody
    public String register(@RequestBody TUserVo tUserVo, HttpServletRequest request) throws NoSuchAlgorithmException {
        System.out.println("注册中");
        tUserVo.setId(idWorker.nextId());
        if ("".equals(tUserVo.getAccount()) || tUserVo.getAccount()==null){
            return "未填写账号名";
        }
        //判断用户是否存在
        TUser user = new TUser();
        user.setAccount(tUserVo.getAccount());
        if (tUserMapper.selectOne(user) != null){
            return "用户已经存在";
        }
        //
        if ("".equals(tUserVo.getPassword()) || tUserVo.getPassword()==null){
            return "未填写密码";        }
        if ("".equals(tUserVo.getNickname()) || tUserVo.getNickname()==null){
            return "未填写name";
        }
        if ("".equals(tUserVo.getEmail()) || tUserVo.getEmail()==null){
            return "未填写email";
        }
        if (!EmailUtils.validate(tUserVo.getEmail())){
            return "邮箱格式不对";
        }
        if ("".equals(tUserVo.getTel()) || tUserVo.getTel()==null){
            return "未填写电话";
        }
        if (!TelUtils.validate(tUserVo.getTel())) {
            return "电话格式错误";
        }
        if ("".equals(tUserVo.getUserImg()) || tUserVo.getUserImg()==null){
            return "未上传图片";
        }
        String hashedPassword = PasswordUtils.passwordEncrypt(tUserVo.getPassword());//密码加密



        //
        //验证码验证
        // 从 session 中获取验证码
        //HttpSession session = request.getSession();
        //String emailVerificationCode = (String) session.getAttribute("email_verification_code");

        //
        //连接 Redis
        HashOperations ops = stringRedisTemplate.opsForHash();
        //从redis中取出验证码
        Object emailVerificationCode = ops.get("verifyCode", tUserVo.getEmail() + "");
        //

        // 获取用户输入的验证码
        //String verificationCode = request.getParameter("verification_code");

        // 进行验证。
        if (emailVerificationCode.equals(tUserVo.getVerifyCode())){
            tUserVo.setPassword(hashedPassword);
            System.out.println(tUserVo.toString());
            int insert = tUserMapper.insert(tUserVo);
            return "success";
        } else {
            return "验证码错误";
        }
        //

    }



    /**
     * 验证码发送，通过邮件
     * 使用redis
     * @param to
     * @param subject
     */
    @RequestMapping("/sendEmail")
    @ResponseBody
    public String sendEmail(@RequestParam("to") String to,@RequestParam("subject") String subject,HttpServletRequest request) throws MessagingException {
        System.out.println("正在发送邮件");
        System.out.println(to);
        MimeMessage mimeMailMessage = javaMailSender.createMimeMessage();

        MimeMessageHelper message = new MimeMessageHelper(mimeMailMessage,true);
        //
        //调用 VerificationCodeService 生产验证码
        String verifyCode = verificationCodeService.generateVerificationCode();

        //获取会话
        //HttpSession session = request.getSession();
        //存入验证码
        //session.setAttribute("email_verification_code", verifyCode);

        //
        //连接 Redis
        HashOperations ops = stringRedisTemplate.opsForHash();
        //存储验证码
        ops.put("verifyCode",to +"",verifyCode);
        //

        //创建邮件正文
        Context context = new Context();
        context.setVariable("verifyCode", Arrays.asList(verifyCode.split("")));

        //将模块引擎内容解析成html字符串
        String emailContent = templateEngine.process("EmailVerificationCode", context);

        //
        message.setTo(to);
        message.setSubject(subject);
        message.setText(emailContent,true);
        message.setFrom("admin@owncup.top");
        message.setReplyTo("admin@owncup.top");


        try {
            javaMailSender.send(mimeMailMessage);
        } catch (MailException e) {
            e.printStackTrace();
        }

        return "success";
    }

    /**
     * 找回密码
     * 使用redis取验证码
     * 邮件验证
     * @param tUserVo
     */
    @RequestMapping("/findPasswordSendEmail")
    @ResponseBody
    public String findPasswordSendEmail(@RequestBody TUserVo tUserVo, HttpServletRequest request) throws NoSuchAlgorithmException {
        if ("".equals(tUserVo.getAccount()) || tUserVo.getAccount()==null){
            return "未填写账号名";
        }
        //判断用户是否存在
        TUser user = new TUser();
        user.setAccount(tUserVo.getAccount());
        if (tUserMapper.selectOne(user) == null){
            return "用户不存在";
        }
        //
        if ("".equals(tUserVo.getEmail()) || tUserVo.getEmail()==null){
            return "未填写email";
        }
        if (!EmailUtils.validate(tUserVo.getEmail())){
            return "邮箱格式不对";
        }
        TUser user2 = new TUser();
        user2.setAccount(tUserVo.getAccount());
        user2.setEmail(tUserVo.getEmail());
        if (tUserMapper.selectOne(user2) == null){
            return "邮箱错误";
        }

        //验证码验证
        // 从 session 中获取验证码
        //HttpSession session = request.getSession();
        //String emailVerificationCode = (String) session.getAttribute("email_verification_code");

        //提供操作redis中操作hash类型的模版类
        HashOperations ops = stringRedisTemplate.opsForHash();
        //获取验证码，从redis中
        Object emailVerificationCode = ops.get("verifyCode", tUserVo.getEmail() + "");

        // 获取用户输入的验证码
        //String verificationCode = request.getParameter("verification_code");

        // 进行验证。
        if (emailVerificationCode.equals(tUserVo.getVerifyCode())){
            TUser user3 = tUserMapper.selectOne(user);
            String hashedPassword = PasswordUtils.passwordEncrypt(tUserVo.getPassword());//密码加密
            user3.setPassword(hashedPassword);

            //验证升级成功
            if (tUserMapper.updateByPrimaryKey(user3) == 0){
                return "error";
            }
            return "success";
        } else {
            return "验证码错误";
        }
    }

    /**
     * 找回密码
     * @return
     */
    @RequestMapping("/findPassword")
    public String findPassword(@RequestBody TUser tUser){
        if ("".equals(tUser.getAccount()) || tUser.getAccount()==null){
            return "未填写账号名";
        }
        //判断用户是否存在
        TUser user = new TUser();
        user.setAccount(tUser.getAccount());
        if (tUserMapper.selectOne(user) == null){
            return "用户不存在";
        }
        //
        if ("".equals(tUser.getEmail()) || tUser.getEmail()==null){
            return "未填写email";
        }
        if (!EmailUtils.validate(tUser.getEmail())){
            return "邮箱格式不对";
        }
        TUser user2 = new TUser();
        user2.setAccount(tUser.getAccount());
        user2.setAccount(tUser.getEmail());
        if (tUserMapper.selectOne(user2) == null){
            return "邮箱错误";
        }
        TUser user3 = tUserMapper.selectOne(user);
        user3.setPassword(tUser.getPassword());

        //验证升级成功
        if (tUserMapper.updateByPrimaryKey(user3) == 0){
            return "error";
        }
        return "success";

    }

    /**
     * 使用拦截器，检查是否含有认证标头
     */
    @RequestMapping("/protected")
    @ResponseBody
    public ResponseEntity<String> getProtectedResource(HttpServletRequest request) {
        // 检查是否包含认证标头
        String authHeader = (String) request.getAttribute("Authorization");
        if (authHeader == null || authHeader.isEmpty()) {
            // 没有认证标头
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Authentication required");
        }

        // 在此处校验令牌的有效性
        // ...

        return ResponseEntity.ok("You have accessed the protected resource.");
    }

}
